#include "Hall.h"
#include "LogEx.h"
#include "StackTrace.h"
#include "PlayerBase.h"
#include "RoomBase.h"
#include "SessionManager.h"
#include "ServerManager.h"
#include "Utils.h"
#include <json/json.h>
#include "msg_common.h"
#include "msg_msgid.h"
#include "msg_errno.h"
#include "msg_dbcommon.h"
#include "msg_center.h"
#include "msg_roomcenter.h"
#include "msg_public.h"
#include "msg_nn5.h"

using namespace std;

void CHall::OnMsgUserAuthenReq(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
	commonproto::CSGameAuthenReq req;
	if( req.ParseFromArray((const char*)msg, len) != len )
	{
		LOG_ERROR( "OnMsgUserAuthenReq ParseFromArray failed. gateid[%llu] clientid[%llu]", gateid, clientid );
        return;
    }

/*
    u64 userid = req.userid;
    CPlayerBase *old = FindPlayer( userid );
    if( old )
    {
        LOG_WARN( "OnMsgUserAuthenReq find old player. gateid[%llu] clientid[%llu] user[%llu]", 
            gateid, clientid, userid );
        _BreakUserComeBack( *old, userid, gateid, clientid, req.token );
    }
    else //*/
    {
        dbcommon::GameDBProxyUserLoginReq m;
        PackBackData( m.bdata, req.userid, gateid, clientid );
        m.userid = req.userid;
        m.token = req.token;
        m.gameid = m_gameid;
        m.roommode = CHallConfig::Instance().GetCfg().roomMode;
	    bool ret = SendMsg2DBProxy( dbcommon::GAME_DBPROXY_USER_LOGIN_REQ, m, req.userid );
        LOG_INFO( "[%s][%s][%d] user[%llu][%llu][%llu] token[%s] roommode[%d] sendret[%d]", 
            __FILE__, __FUNCTION__, __LINE__,
            req.userid, gateid, clientid, req.token.c_str(), m.roommode, ret?1:0 );
    }
}

void CHall::OnMsgUserClose(u64 gateid, u64 clientid)
{
	CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
		LOG_ERROR( "OnMsgUserClose not found player. gateid[%llu] clientid[%llu]", gateid, clientid );
        return;
    }

	PlayerLeaveHall( *player, commonproto::E_LeaveReason_ConnBreak );
}

void CHall::OnMsgUserEnterRoomReq(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
	CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
		LOG_ERROR( "OnMsgUserEnterRoomReq not found player, not login. gateid[%llu] clientid[%llu]", gateid, clientid );
		return;
	}

    commonproto::CSEnterRoomReq req;
	if( req.ParseFromArray((const char*)msg, len) != len )
	{
		LOG_ERROR( "OnMsgUserEnterRoomReq ParseFromArray error. player[%llu,%llu][%llu]", 
			player->GateId(), player->ClientId(), player->UserId() );
		return;
	}
    
    CRoomBase *room = FindRoom( req.roomid );
	if( !room )
	{
		LOG_ERROR( "OnMsgUserEnterRoomReq not found room. player[%llu,%llu][%llu] state[%d] room[%d]", 
			player->GateId(), player->ClientId(), player->UserId(), player->State(), req.roomid );
		return;
	}

    if( (req.seatno != commonproto::E_SeatType_AutoSeat) && (req.seatno < -1 || req.seatno >= MaxRoomPlayerCount()) )
    {
		LOG_ERROR( "OnMsgUserEnterRoomReq seatno[%d] error. player[%llu,%llu][%llu]", 
			req.seatno, player->GateId(), player->ClientId(), player->UserId() );
		return;
    }

    PlayerEnterRoom( *player, *room, req.seatno, req.password );
}

void CHall::OnMsgUserLeaveRoomReq(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
	CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
		LOG_ERROR( "OnMsgUserLeaveRoomReq not found player, not login. gateid[%llu] clientid[%llu]", gateid, clientid );
		return;
	}

	PlayerLeaveRoom( *player, commonproto::E_LeaveReason_SelfOp );
}

void CHall::OnMsgUserSitDownReq(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
	CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
		LOG_ERROR( "OnMsgUserSitDownReq not found player, not login. gateid[%llu] clientid[%llu]", gateid, clientid );
		return;
	}
	
    commonproto::CSSitDownReq req;
	if( req.ParseFromArray((const char*)msg, len) != len )
	{
		LOG_ERROR( "OnMsgUserSitDownReq ParseFromArray error. player[%llu,%llu][%llu]", 
			player->GateId(), player->ClientId(), player->UserId() );
		return;
	}

    if( req.seatno < 0 || req.seatno >= MaxRoomPlayerCount() )
    {
		LOG_ERROR( "OnMsgUserSitDownReq seatno[%d] error. player[%llu,%llu][%llu]", 
			req.seatno, player->GateId(), player->ClientId(), player->UserId() );
		return;
    }

	PlayerSitDown( *player, req.seatno );
}

void CHall::OnMsgUserStandUpReq(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
	CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
		LOG_ERROR( "OnMsgUserStandUpReq not found player, not login. gateid[%llu] clientid[%llu]", gateid, clientid );
		return;
	}
	
	PlayerStandUp( *player );
}

void CHall::OnMsgUserReady(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
	CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
		LOG_ERROR( "OnMsgUserReady not found player, not login. gateid[%llu] clientid[%llu]", gateid, clientid );
		return;
	}

    PlayerReady( *player );
}

void CHall::OnMsgUserCancelReady(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
	CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
		LOG_ERROR( "OnMsgUserCancelReady not found player, not login. gateid[%llu] clientid[%llu]", gateid, clientid );
		return;
	}

    PlayerCancelReady( *player );
}

void CHall::OnMsgUserTrusteeShip(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
		LOG_ERROR( "OnMsgUserTrusteeShip not found player, not login. gateid[%llu] clientid[%llu]", gateid, clientid );
		return;
	}

    PlayerTrusteeShip( *player );
}

void CHall::OnMsgUserCancelTrusteeShip(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
		LOG_ERROR( "OnMsgUserCancelTrusteeShip not found player, not login. gateid[%llu] clientid[%llu]", gateid, clientid );
		return;
	}

    PlayerCancelTrusteeShip( *player );
}

void CHall::OnMsgUserRoomChat(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
		LOG_ERROR( "OnMsgUserRoomChat not found player, not login. gateid[%llu] clientid[%llu]", gateid, clientid );
		return;
	}

    commonproto::CSRoomChatReq req;
	if( req.ParseFromArray((const char*)msg, len) != len )
	{
		LOG_ERROR( "OnMsgUserRoomChat ParseFromArray error. player[%llu,%llu][%llu]", 
			player->GateId(), player->ClientId(), player->UserId() );
		return;
	}

    if( req.chattype <= commonproto::E_RoomChatType_Invalid ||
        req.chattype >= commonproto::E_RoomChatType_Count )
    {
		LOG_ERROR( "OnMsgUserRoomChat player[%llu,%llu][%llu] chattype[%d] error", 
			player->GateId(), player->ClientId(), player->UserId(), req.chattype );
		return;
    }

    PlayerRoomChat( *player, req.chattype, req.chatcontent, req.anonymous, req.receiver, req.isend, req.param );
}

void CHall::OnMsgUserCreateRoom(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
        LOG_INFO( "[%s][%s][%d] not found player. gateid[%llu] clientid[%llu]", 
            __FILE__, __FUNCTION__, __LINE__, 
            gateid, clientid );
		return;
	}

    commonproto::CSCreateRoomReq req;
    CHECK_PARSE_MSG( req, msg, len );

    PlayerCreateRoom( *player, req.name, req.passwd, req.ante, req.data );
}

void CHall::OnMsgMatchPlayer(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
        LOG_INFO( "[%s][%s][%d] not found player. gateid[%llu] clientid[%llu]", 
            __FILE__, __FUNCTION__, __LINE__, 
            gateid, clientid );
		return;
	}

    commonproto::CSMatchPlayerReq req;
    CHECK_PARSE_MSG( req, msg, len );

    PlayerMatchRequest( *player );
}

void CHall::OnMsgSetRoomAnte(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
        LOG_INFO( "[%s][%s][%d] not found player. gateid[%llu] clientid[%llu]", 
            __FILE__, __FUNCTION__, __LINE__, 
            gateid, clientid );
		return;
	}

    commonproto::CSSetRoomAnteReq req;
    CHECK_PARSE_MSG( req, msg, len );

    PlayerSetRoomAnte( *player, req.ante );
}

void CHall::OnMsgGetRoomList(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
        LOG_INFO( "[%s][%s][%d] not found player. gateid[%llu] clientid[%llu]", 
            __FILE__, __FUNCTION__, __LINE__, 
            gateid, clientid );
		return;
	}

    PlayerGetRoomList( *player );
}

void CHall::OnMsgGetActivityAward(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
	if( !player )
	{
        LOG_INFO( "[%s][%s][%d] not found player. gateid[%llu] clientid[%llu]", 
            __FILE__, __FUNCTION__, __LINE__, 
            gateid, clientid );
		return;
	}

    commonproto::CSGetActivityAwardReq req;
    CHECK_PARSE_MSG( req, msg, len );

    PlayerGetActivityAward( *player, req.activityid );
}

void CHall::OnMsgDBProxyUserLogin(const byte *msg, s32 len)
{
    dbcommon::DBProxyGameUserLoginRsp m; 
    CHECK_PARSE_MSG( m, msg, len );

    publicproto::BackData bd;
    CHECK_PARSE_MSG( bd, m.bdata.c_str(), m.bdata.length() );

    SELF_ASSERT( m.result.size() > 0 && m.basicinfo.size() > 0, return; );

    LOG_DEBUG( "[%s][%s][%d] user[%llu][%llu][%llu] result[%d] head[%d,%s]name[%s]sex[%d]level[%u,%llu]money[%lld,%lld,%lld,%lld,%lld] uuid[%llu]",
        __FILE__, __FUNCTION__, __LINE__, 
        bd.userid, bd.gateid, bd.clientid, m.result[0].result,
        m.basicinfo[0].headid, m.basicinfo[0].headurl.c_str(), m.basicinfo[0].nickname.c_str(), m.basicinfo[0].sex,
        m.basicinfo[0].level, m.basicinfo[0].exp,
        m.basicinfo[0].money1, m.basicinfo[0].money2, 
        m.basicinfo[0].money3, m.basicinfo[0].money4, m.basicinfo[0].money5, m.basicinfo[0].uuid );
    
    commonproto::SCGameAuthenRsp rsp;
    rsp.result = m.result[0].result;
    if( m.result[0].result != errorcode::E_ErrorCode_Success )
    {
        CHall::Instance().SendMsg( bd.gateid, bd.clientid, commonproto::SC_GAME_AUTHEN_RSP, rsp );
        CHall::Instance().Close( bd.gateid, bd.clientid );
        return;
    }

    // check repeated login
    CPlayerBase *old = CHall::Instance().FindPlayer( bd.userid );
    if( old )
    {
        LOG_WARN( "[%s][%s][%d] user[%llu] cur[%llu][%llu] old[%llu][%llu]",
            __FILE__, __FUNCTION__, __LINE__, 
            bd.userid, bd.gateid, bd.clientid, old->GateId(), old->ClientId() );

        std::string token("");
        _BreakUserComeBack( *old, bd.userid, bd.gateid, bd.clientid, token );

        return;
    }

    CPlayerBase *p = CHall::Instance().PlayerEnterHall( 
        bd.gateid, bd.clientid, bd.userid );
    SELF_ASSERT( p, return; );
    p->LoginResult( m.basicinfo[0], m.gamedata[0] );
}

void CHall::OnMsgCenterUserGetMoney(const byte *msg, s32 len)
{
    center::CenterServerGetUserMoneyRsp m; 
    CHECK_PARSE_MSG( m, msg, len );
	
    CPlayerBase *player = FindPlayer( m.userid );
    if( !player )
    {
        LOG_WARN( "[%s][%s][%d] user[%llu] not online",
            __FILE__, __FUNCTION__, __LINE__, m.userid );
        return;
    }
    LOG_DEBUG( "[%s][%s][%d] user[%llu] money[%llu,%llu] onlineinfo[%d,%llu]",
        __FILE__, __FUNCTION__, __LINE__, 
        m.userid, m.money[0], m.money[1], m.onlineInfo.gameid, m.onlineInfo.serverid );

    PlayerGetCenterMoneyDone( *player, m.money, m.onlineInfo );
}

void CHall::OnMsgCenterUserUpdateMoney(const byte *msg, s32 len)
{
    center::CenterServerUpdateMoneyRsp m; 
    CHECK_PARSE_MSG( m, msg, len );
	
    LOG_INFO( "[%s][%s][%d] user[%llu] upret[%d] reason[%d]",
        __FILE__, __FUNCTION__, __LINE__, m.userid, m.result, m.reason );
}

void CHall::OnMsgDBProxyUserActivityData(const byte *msg, s32 len)
{
    dbcommon::DBProxyGameLoadActivityDataRsp m; 
    CHECK_PARSE_MSG( m, msg, len );

    u64 userid = *((u64*)m.bdata.c_str());
    bool isend = m.isend;
	CPlayerBase *player = FindPlayer( userid );
    if( !player )
    {
        LOG_WARN( "[%s][%s][%d] user[%llu] not online",
            __FILE__, __FUNCTION__, __LINE__, userid );
        return;
    }
    player->InitActivityData( m.datas, isend );
    LOG_INFO( "[%s][%s][%d] user[%llu] activityDataSize[%d] isend[%d]",
        __FILE__, __FUNCTION__, __LINE__, userid, (s32)m.datas.size(), m.isend );
}

void CHall::OnMsgDBProxyLoadUserItems(const byte *msg, s32 len)
{
    dbcommon::DBProxyGameLoadItemsRsp m; 
    CHECK_PARSE_MSG( m, msg, len );

    u64 userid = *((u64*)m.bdata.c_str());
    bool isend = m.isend;
	CPlayerBase *player = FindPlayer( userid );
    if( !player )
    {
        LOG_WARN( "[%s][%s][%d] user[%llu] not online",
            __FILE__, __FUNCTION__, __LINE__, userid );
        return;
    }
    player->InitItems( m.items, isend );
    LOG_INFO( "[%s][%s][%d] user[%llu] itemSize[%d] isend[%d]",
        __FILE__, __FUNCTION__, __LINE__, userid, (s32)m.items.size(), m.isend );
}

void CHall::OnMsgDBProxyCardTypeAward(const byte *msg, s32 len) {
	dbcommon::DBProxyGameCardTypeAwardRsp m;
	CHECK_PARSE_MSG( m, msg, len );
	u64 userid = *((u64*)m.bdata.c_str());
	CPlayerBase* player = FindPlayer( userid );
	if( !player )
	{
	     LOG_WARN( "[%s][%s][%d] user[%llu] not online",
	            __FILE__, __FUNCTION__, __LINE__, userid );
	     return;
	}
	std::vector<dbcommon::CardTypeAwardResult>::iterator it=m.result.begin();
	nn5::SCCardTypeAward ntf;
	ntf.cardtype=it->cardtype;
	ntf.ret=it->result;
	player->SendMsg(nn5::SC_CARDTYPE_AWARD,ntf);
}

static u64 _GetBattleId(s32 serverid, s32 roomid)
{
    struct timeval tv;
    gettimeofday( &tv, NULL );
    time_t tsec = tv.tv_sec;
    struct tm t = { 0 };
    localtime_r( &tsec, &t );
    int year = t.tm_year - 100; // (1900 - 2000) 从2000年开始计数
    int day = t.tm_yday;
    int sec = t.tm_hour * 3600 + t.tm_min * 60 + t.tm_sec;
    char strid[32] = {0};
    sprintf( strid, "%d%d%d%d%d", year, day, sec, serverid, roomid);
    u64 bid = 0;
    sscanf( strid, "%llu", &bid );
    return bid;
}

u64 CHall::GenBattleId(s32 rid)
{
    return _GetBattleId(CServerManager::Instance().GetId(), rid);    
}

void CHall::OnMsgRoomCenterCreatRoom(const byte *msg, s32 len)
{
    roomcenter::RoomCenterGameRoomCreate m;
    CHECK_PARSE_MSG( m, msg, len );
    
    s32 roomMode = CHallConfig::Instance().GetCfg().roomMode;
    u64 sid = CServerManager::Instance().GetId();
    if( m.serverid != sid || roomMode != E_RoomMode_Friend )
    {
        return;
    }

    s32 rid = CRoomManager::Instance().GetRoom( m.roomid );
    if( rid == INVALID_VAL )
    {
        LOG_ERROR( "[%s][%s][%d] creater[%llu] roomid[%d] not found",
            __FILE__, __FUNCTION__, __LINE__, m.creater, m.roomid );
        return;
    }
	
    CRoomBase *room = FindRoom( rid );
    SELF_ASSERT( room, return; );
    
    room->Clean();
    room->GetFriendData()._creater = m.creater;
    room->GetFriendData()._maxRound = m.round;
    room->GetFriendData()._curRound = 0;
    room->GetFriendData()._number = m.number;
    room->GetFriendData()._cfg = m.gamecfg;
    room->GetFriendData()._createTime = TIME_NOW;
    room->GetFriendData()._cardAA = m.cardAA;
    room->GetFriendData()._groupid = m.groupid;
    room->GetFriendData()._ante = m.ante;
    room->GetFriendData()._reserve = m.reserve;
	room->SetState( CRoomBase::E_RoomState_Waiting );
    room->OnFriendRoomCreated( m.gamecfg );
    room->GetFriendData()._battleId = _GetBattleId(CServerManager::Instance().GetId(), rid);
    
    char roompasswd[16] = {0};
    sprintf( roompasswd, "%d", m.number );
    room->SetPasswd( std::string(roompasswd) );

    LOG_INFO( "[%s][%s][%d] creater[%llu] roomid[%d] number[%d] round[%d] cfg[%s] battleid[%llu] AA[%d] groupid[%llu] ante[%d] reserve[%s]",
        __FILE__, __FUNCTION__, __LINE__, 
        m.creater, m.roomid, m.number, m.round, m.gamecfg.c_str(), room->GetFriendData()._battleId,
        m.cardAA, m.groupid, m.ante, m.reserve.c_str() );
}

void CHall::OnMsgFriendRoomDismiss(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    s32 roomMode = CHallConfig::Instance().GetCfg().roomMode;
    if( roomMode != E_RoomMode_Friend )
    {
        return;
    }

    CPlayerBase *player = FindPlayer( gateid, clientid );
    if( !player )
    {
        LOG_ERROR( "[%s] not found player, not login. gateid[%llu] clientid[%llu]", 
            __FUNCTION__, gateid, clientid );
        return;
    }

    PlayerDismissFriendRoom( *player );
}

void CHall::OnMsgFriendRoomLeave(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    s32 roomMode = CHallConfig::Instance().GetCfg().roomMode;
    if( roomMode != E_RoomMode_Friend )
    {
        return;
    }

    CPlayerBase *player = FindPlayer( gateid, clientid );
    if( !player )
    {
        LOG_ERROR( "[%s] not found player, not login. gateid[%llu] clientid[%llu]", 
            __FUNCTION__, gateid, clientid );
        return;
    }

    PlayerLeaveFriendRoom( *player );
}

void CHall::OnMsgFriendRoomAgreeDismiss(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    s32 roomMode = CHallConfig::Instance().GetCfg().roomMode;
    if( roomMode != E_RoomMode_Friend )
    {
        return;
    }

    commonproto::CSFriendRoomAgreeDismiss m;
    CHECK_PARSE_MSG( m, msg, len );

    CPlayerBase *player = FindPlayer( gateid, clientid );
    if( !player )
    {
        LOG_ERROR( "[%s] not found player, not login. gateid[%llu] clientid[%llu]", 
            __FUNCTION__, gateid, clientid );
        return;
    }

    PlayerAgreeDismissFriendRoom( *player, m.agree );
}

void CHall::OnMsgFriendRoomStartGame(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    s32 roomMode = CHallConfig::Instance().GetCfg().roomMode;
    if( roomMode != E_RoomMode_Friend )
    {
        return;
    }

    CPlayerBase *player = FindPlayer( gateid, clientid );
    if( !player )
    {
        LOG_ERROR( "[%s] not found player, not login. gateid[%llu] clientid[%llu]", 
            __FUNCTION__, gateid, clientid );
        return;
    }

    PlayerStartGameFriendRoom( *player );
}

void CHall::OnMsgSelfLocationInfo(u64 gateid, u64 clientid, u32 remoteip, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
    if( !player )
    {
        LOG_ERROR( "[%s] not found player, not login. gateid[%llu] clientid[%llu]", 
            __FUNCTION__, gateid, clientid );
        return;
    }

    commonproto::CSSelfLocationInfo m;
    CHECK_PARSE_MSG( m, msg, len );

    string strip = ConvertIp( remoteip );
    string location = "{}";

    try
    {
        Json::Reader reader;
        Json::Value root;
        if( reader.parse(m.info.c_str(), root) )
        {
            root["ip"] = strip;
            Json::FastWriter writer;
            location = writer.write( root );
        }
    }
    catch( ... )
    {
        location = "{err:1}";
    }
    player->m_locationInfo = location;

    LOG_INFO( "[%s] user[%llu] location[%s] ip[%s] retloc[%s]", 
        __FUNCTION__, player->UserId(), 
        m.info.c_str(), strip.c_str(), location.c_str() );
}

void CHall::OnMsgKickOutRoom(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
    if( !player )
    {
        LOG_ERROR( "[%s] not found player, not login. gateid[%llu] clientid[%llu]", 
            __FUNCTION__, gateid, clientid );
        return;
    }

    commonproto::CSKickOutRoomReq m;
    CHECK_PARSE_MSG( m, msg, len );

    KickOutRoom( *player, m.kickuser );
}

void CHall::OnMsgUseInteractItem(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
    if( !player )
    {
        LOG_ERROR( "[%s] not found player, not login. gateid[%llu] clientid[%llu]", 
            __FUNCTION__, gateid, clientid );
        return;
    }

    commonproto::CSUseInteractItemReq m;
    CHECK_PARSE_MSG( m, msg, len );
    UseInteractItem(*player, m.toseat, m.item);
}

void CHall::OnMsgUserCuiPai(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
    if( !player )
    {
        LOG_ERROR( "[%s] not found player, not login. gateid[%llu] clientid[%llu]", 
            __FUNCTION__, gateid, clientid );
        return;
    }

    commonproto::CSUserCuiPaiReq m;
    CHECK_PARSE_MSG( m, msg, len );
    UserCuiPai(*player, m.cuipai);
}

void CHall::OnMsgGetUserInfo(u64 gateid, u64 clientid, const byte *msg, s32 len)
{
    CPlayerBase *player = FindPlayer( gateid, clientid );
    if( !player )
    {
        LOG_ERROR( "[%s] not found player, not login. gateid[%llu] clientid[%llu]", 
            __FUNCTION__, gateid, clientid );
        return;
    }

    commonproto::CSGetUserInfoReq m;
    CHECK_PARSE_MSG( m, msg, len );
    GetUserInfo(*player, m.userid);
}

void CHall::OnMsgCenterUserRecharge(const byte *msg, s32 len)
{
    center::CenterServerUserRecharge m;
    CHECK_PARSE_MSG( m, msg, len );

    CPlayerBase *player = FindPlayer( m.userid );
    if( !player )
    {
        LOG_WARN( "[%s][%s][%d] user[%llu] not online",
            __FILE__, __FUNCTION__, __LINE__, m.userid );
        return;
    }

    player->DoUpdateMoney( commonproto::E_MoneyType_1, m.rechargeCount );
    commonproto::SCMoneyUpdateNtf ntf;
    ntf.reason = center::E_UseMoney_Recharge;
    ntf.upcount = m.rechargeCount;
    ntf.curcount = player->GetMoney( commonproto::E_MoneyType_1 );
    player->SendMsg( commonproto::SC_MONEY_UPDATE_NTF, ntf );

    LOG_INFO( "[%s][%s][%d] user[%llu] recharge[%llu] now[%lld]",
        __FILE__, __FUNCTION__, __LINE__, 
        m.userid, m.rechargeCount, ntf.curcount );
}



